#pragma once

#include <unistd.h>
#include <atomic>
#include "ShmMutex.hpp"
#include "ShmCond.hpp"
#include "ShmScopedLock.hpp"
#include "LOG_CYC.hpp"


#define BUFSIZE 32

class ShmMemoryBlock {
public:
    int32_t _shmID;     // 标记使用共享内存文件编号
    int32_t _shmPos;    // 标记分配的共享内存区域起始位偏移量
    int32_t _blockSize; // 块大小

    // 默认构造函数
    ShmMemoryBlock()
        : _shmID(-1)
        , _shmPos(-1)
        , _blockSize(-1) {}

    // 带参数的构造函数
    ShmMemoryBlock(int32_t shmID, int32_t shmPos, int32_t blockSize)
        : _shmID(shmID)
        , _shmPos(shmPos)
        , _blockSize(blockSize) {}

    // 拷贝构造函数
    ShmMemoryBlock(const ShmMemoryBlock& other)
        : _shmID(other._shmID)
        , _shmPos(other._shmPos)
        , _blockSize(other._blockSize) {}

    // 赋值运算符重载
    ShmMemoryBlock& operator=(const ShmMemoryBlock& other) {
        if (this != &other) {
            _shmID = other._shmID;
            _shmPos = other._shmPos;
            _blockSize = other._blockSize;
        }
        return *this;
    }

    // 移动构造函数
    ShmMemoryBlock(ShmMemoryBlock&& other) noexcept
        : _shmID(other._shmID)
        , _shmPos(other._shmPos)
        , _blockSize(other._blockSize) {
        // 移动后将源对象的成员变量重置为默认值
        other._shmID = -1;
        other._shmPos = -1;
        other._blockSize = -1;
    }

    // 移动赋值运算符重载
    ShmMemoryBlock& operator=(ShmMemoryBlock&& other) noexcept {
        if (this != &other) {
            _shmID = other._shmID;
            _shmPos = other._shmPos;
            _blockSize = other._blockSize;

            // 移动后将源对象的成员变量重置为默认值
            other._shmID = -1;
            other._shmPos = -1;
            other._blockSize = -1;
        }
        return *this;
    }
};


class DataStructureBlock {
public:
    uint16_t _dataStructureType;        // 数据结构类型
    uint16_t _functionType; // 数据结构功能类型
    char buffer[BUFSIZE];               // 数据缓冲区

    // 默认构造函数
    DataStructureBlock()
        : _dataStructureType(0)
        , _functionType(0) {
        std::memset(buffer, 0, BUFSIZE);
    }

    // 带参数的构造函数
    DataStructureBlock(uint16_t dataType, uint16_t functionType, const std::string& data)
        : _dataStructureType(dataType)
        , _functionType(functionType) {
        size_t dataSize = data.size();
        if (dataSize < BUFSIZE) {
            std::memcpy(buffer, data.c_str(), dataSize);
            buffer[dataSize] = '\0';  // 添加字符串结尾符
        }
        else {
            std::memcpy(buffer, data.c_str(), BUFSIZE - 1);
            buffer[BUFSIZE - 1] = '\0';  // 确保缓冲区以null结尾
        }
    }

    // 拷贝构造函数
    DataStructureBlock(const DataStructureBlock& other)
        : _dataStructureType(other._dataStructureType)
        , _functionType(other._functionType) {
        std::memcpy(buffer, other.buffer, BUFSIZE);
    }

    // 赋值运算符重载
    DataStructureBlock& operator=(const DataStructureBlock& other) {
        if (this != &other) {
            _dataStructureType = other._dataStructureType;
            _functionType = other._functionType;
            std::memcpy(buffer, other.buffer, BUFSIZE);
        }
        return *this;
    }
};

enum ShmFunctionType {
    funcNULL,
    AllocateSharedMemory,
    ReleaseSharedMemory,
    DataStructure
};

class ShmMessageNode {
public:
    // 构造函数，初始化节点状态
    ShmMessageNode()
        : _size(-1),
        _isUse(false),
        _functionType(ShmFunctionType::funcNULL), // 默认功能类型为 FunctionType1
        _nodePos(-1),
        _next(-1),
        _executeSuccess(false) {}

    // 等待分配
    void Wait() {
        while (_isUse && !_executeSuccess) {
            LOG_CYC(WARNING, "等待分配中", nullptr);
            _shmCond.Wait(_shmMutex);
        }
    }

    // 发送信号
    void Signal() {
        _shmCond.Signal();
        // _shmCond.Broadcast();
    }

    // Getter 方法
    ShmMemoryBlock GetShmMemoryBlock() const { return _shmMemoryBlock; }

    DataStructureBlock GetDataStructureBlock() const { return _dataStructureBlock; }

    ShmMutex& GetMutex() { return _shmMutex; }

    ShmCond& GetCond() { return _shmCond; }

    int GetSize() const { return _size; }

    int GetNodePos() const { return _nodePos; }

    int GetNext() const { return _next; }

    int GetFunctionType() const { return _functionType; }


    bool IsUse() const { return _isUse; }

    // 获取功能执行是否成功的标志位
    bool isExecuteSuccessful() const { return _executeSuccess; }

    // Setter 方法
    void SetShmMemoryBlock(int32_t shmID, int32_t ShmPos, int32_t blockSize) {
        _shmMemoryBlock._shmID = shmID;
        _shmMemoryBlock._shmPos = ShmPos;
        _shmMemoryBlock._blockSize = blockSize;
    }

    void SetDataStructureBlock(uint16_t dataStructureType, uint16_t functionType, const std::string& data) {
        // 设置数据结构块的类型和功能类型
        _dataStructureBlock._dataStructureType = dataStructureType;
        _dataStructureBlock._functionType = functionType;

        // 复制数据到缓冲区，确保不超过缓冲区大小
        size_t dataSize = data.size();
        if (dataSize < BUFSIZE) {
            std::memcpy(_dataStructureBlock.buffer, data.c_str(), dataSize);
            _dataStructureBlock.buffer[dataSize] = '\0';  // 添加字符串结尾符
        }
        else {
            std::memcpy(_dataStructureBlock.buffer, data.c_str(), BUFSIZE - 1);
            _dataStructureBlock.buffer[BUFSIZE - 1] = '\0';  // 确保缓冲区以null结尾
        }
    }

    void SetSize(int size) { _size = size; }

    void SetNodePos(int pos) { if (_nodePos == -1) _nodePos = pos; }

    void SetNext(int next) { _next = next; }

    void SetFunctionType(ShmFunctionType functionType) {
        // 检查 functionType 是否在有效范围内
        if (functionType < funcNULL || functionType > DataStructure) {
            throw std::out_of_range("ShmFunctionType 值超出范围");
        }
        _functionType = functionType;
    }

    void SetUse(bool acquiring) { _isUse = acquiring; }

    // 设置功能执行成功的标志位为true
    void SetExecuteSuccess(bool success) { _executeSuccess = success; }

private:
    ShmMemoryBlock _shmMemoryBlock;        // 记录共享内存块属性
    int _size;                      // 申请的共享内存大小
    ShmFunctionType _functionType;  // 功能类型枚举值，表示当前节点的功能
    DataStructureBlock _dataStructureBlock;

    bool _executeSuccess;       // 功能是否执行成功的标志位


    ShmCond _shmCond;   // 封装的条件变量
    ShmMutex _shmMutex; // 封装的互斥锁

    int _nodePos;       // 自身在节点在池中的位置
    int _next;          // 下一个节点的索引
    bool _isUse;        // 是否被使用
};